package cn.dduan.fool.design.pattern.structure.facade;

/**
 * 外观模式
 * <p>
 * 核心：外观模式通过对客户端提供一个统一的接口，用于访问子系统中的一群接口
 * <p>
 * 优点：
 * 1、更加易用：使得子系统更加易用，客户端不再需要了解子系统内部的实现，也不需要跟众多子系统内部的模块进行交互，只需要跟外观类交互就可以了
 * 2、松散耦合：将客户端与子系统解耦，让子系统内部的模块能更容易扩展和维护
 * 3、更好的划分访问层次
 * <p>
 * 缺点：
 * 1、并不能限制客户端直接调用子系统，如果客户端对子系统类做太多限制则减少了可变形和灵活性
 * 2、如果设计不当，增加新的子系统就可能修改外观类的源代码，不符合开闭原则
 * <p>
 * 注意：
 * 1、在外观模式中，通常只需要一个外观类，并且此外观类只有一个实例，也就是单例类
 * 2、但这并不意味着在整个系统里只有一个外观类，而仅仅是说对每一个子系统只有一个外观类。
 * 3、或者说，如果一个系统有好几个子系统的话，每一个子系统都有一个外观类，整个系统可以有数个外观类
 * <p>
 * 应用场景：
 * 1、当客户端需要调用一系列复杂子系统时候，可以提供一个简单入口的时候使用外观模式
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/7
 */
public class FacadePattern {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.startup();
        computer.shutdown();
    }
}

/**
 * 子类1
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/7
 */
class CPU {

    public void startup() {
        System.out.println("cpu startup!");
    }

    public void shutdown() {
        System.out.println("cpu shutdown!");
    }
}

/**
 * 子类2
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/7
 */
class Memory {

    public void startup() {
        System.out.println("memory startup!");
    }

    public void shutdown() {
        System.out.println("memory shutdown!");
    }
}

/**
 * 子类3
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/7
 */
class Disk {

    public void startup() {
        System.out.println("disk startup!");
    }

    public void shutdown() {
        System.out.println("disk shutdown!");
    }
}

/**
 * Facade类
 *
 * @author dduan
 * @version 1.0
 * @date 2023/4/7
 */
class Computer {
    private CPU cpu;
    private Memory memory;
    private Disk disk;

    public Computer() {
        cpu = new CPU();
        memory = new Memory();
        disk = new Disk();
    }

    public void startup() {
        System.out.println("start the computer!");
        cpu.startup();
        memory.startup();
        disk.startup();
        System.out.println("start computer finished!");
    }

    public void shutdown() {
        System.out.println("begin to close the computer!");
        cpu.shutdown();
        memory.shutdown();
        disk.shutdown();
        System.out.println("computer closed!");
    }
}